home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / das / passb.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  4KB  |  155 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  PASSB.C
  9.  *
  10.  *  Everything has been resolved into opcodes, properly placed in their
  11.  *  section, and all EQU and REG directives have been figured out.  We
  12.  *  can now scan the list and resolve the addressing modes.
  13.  *
  14.  *  XDEFd labels must be added to the appropriate section list
  15.  */
  16.  
  17. /*
  18. **      $Filename: passb.c $
  19. **      $Author: dice $
  20. **      $Revision: 30.0 $
  21. **      $Date: 1994/06/10 18:07:45 $
  22. **      $Log: passb.c,v $
  23.  * Revision 30.0  1994/06/10  18:07:45  dice
  24.  * .
  25.  *
  26.  * Revision 1.1  1993/09/19  19:56:46  jtoebes
  27.  * Initial revision
  28.  *
  29. **/
  30.  
  31. #include "defs.h"
  32.  
  33. Prototype void    PassB(void);
  34.  
  35. void
  36. PassB()
  37. {
  38.     MachCtx **pmc;
  39.     MachCtx *mc;
  40.     OpCod   *oc;
  41.     char    *str;
  42.     long i;
  43.     long addr = 0;
  44.  
  45.     pmc = MBase;
  46.     for (i = 0; i < MLines; ++i) {
  47.     mc = *pmc++;
  48.     LineNo = mc->LineNo;
  49.     mc->m_Addr = addr;
  50.     if (mc->Label)
  51.         mc->Label->l_Offset = addr;
  52.     if ((oc = mc->OpCode) == NULL)
  53.         continue;
  54.     if (oc->Id < 0) {
  55.         addr = ExecOpCodeB(mc, addr);
  56.         continue;
  57.     }
  58.  
  59.     if (oc->Id >= LIMIT68000 && MC68020 == 0)
  60.         cerror(EWARN_68020);
  61.  
  62.     str = mc->m_Operands;
  63.  
  64.     if (mc->OpSize == 1) {
  65.         mc->Oper1.ISize |= ISF_INSTBYTE;
  66.         mc->Oper2.ISize |= ISF_INSTBYTE;
  67.     }
  68.     if (*str) {
  69.         str = ParseEffAddr(str, &mc->Oper1);
  70.     }
  71.     if (*str == ',') {
  72.         str = ParseEffAddr(str + 1, &mc->Oper2);
  73.     }
  74.     dbprintf(0, ("%s %s,%s\n", oc->OpName, EAToString(&mc->Oper1), EAToString(&mc->Oper2)));
  75.     while (*str == ' ' || *str == 9)
  76.         ++str;
  77.     if (*str)
  78.         cerror(EWARN_GARBAGE, str);
  79.  
  80.     /*
  81.      *  Find a valid op code for the addressing modes.  Remember
  82.      *  to check the secondary Modes.
  83.      *
  84.      *  note: ok of Mode1/2 is 0, bit 0 not used in modes bits.
  85.      */
  86.  
  87.     {
  88.         long mc10= (1 << mc->Oper1.Mode1);
  89.         long mc1 = mc10 | (1 << mc->Oper1.Mode2);
  90.         long mc20= (1 << mc->Oper2.Mode1);
  91.         long mc2 = mc20 | (1 << mc->Oper2.Mode2);
  92.  
  93.         for (; oc; oc = oc->SibNext) {
  94.         {
  95.             if (mc->OpSize && (oc->Sizes & (1 << mc->OpSize)) == 0)
  96.             continue;
  97.         }
  98.  
  99.         if (oc->SModes && oc->DModes) {
  100.             if ((oc->SModes & mc1) && (oc->DModes & mc2)) {
  101.             if ((oc->SModes & mc10) == 0)    /*  secondary */
  102.                 mc->Oper1.Mode1 = mc->Oper1.Mode2;
  103.             if ((oc->DModes & mc20) == 0)   /*  secondary */
  104.                 mc->Oper2.Mode1 = mc->Oper2.Mode2;
  105.             break;
  106.             }
  107.         } else if (oc->SModes) {
  108.             if (oc->SModes & mc1) {
  109.             if ((oc->SModes & mc10) == 0)    /*  secondary */
  110.                 mc->Oper1.Mode1 = mc->Oper1.Mode2;
  111.             break;
  112.             }
  113.         } else if (oc->DModes) {
  114.             if (oc->DModes * mc1) {
  115.             if ((oc->DModes & mc10) == 0)   /*  secondary */
  116.                 mc->Oper1.Mode1 = mc->Oper1.Mode2;
  117.             mc->Oper2 = mc->Oper1;        /*  copy so matches oc */
  118.             mc->Oper1.Mode1 = 0;        /*  turn off oper2     */
  119.             mc->Oper1.Label1 = NULL;    /*  so passg doesn't get confused */
  120.             break;
  121.             }
  122.         } else {
  123.             if (mc->Oper1.Mode1)
  124.             cerror(EERROR_TAKES_NO_OPS, oc->OpName);
  125.             break;
  126.         }
  127.         }
  128.         if (oc == NULL)
  129.         cerror(EERROR_ILLEGAL_ADDR_MODES, mc->Oper1.Mode1, mc->Oper2.Mode1, mc->OpCode->OpName);
  130.         mc->OpCode = oc;
  131.     }
  132.  
  133.     /*
  134.      *  check for subroutine calls and references to A5 for passC.
  135.      *  note, register check assumes Oper*.Reg1 zero when non-register
  136.      *  modes are used.
  137.      */
  138.  
  139.         if (oc)
  140.         {
  141.             if (oc->Id == OpBSR || oc->Id == OpJSR)
  142.                 SetSubroutineCallFlag();
  143.  
  144.             if (oc->B_Rs >= 0 && mc->Oper1.Reg1 == RB_AREG+5 && oc->Id != OpLINK)
  145.                 SetA5UsedFlag();
  146.             if (oc->B_Rd >= 0 && mc->Oper2.Reg1 == RB_AREG+5 && oc->Id != OpUNLK)
  147.                 SetA5UsedFlag();
  148.     }
  149.  
  150.     addr += GetInstSize(mc);
  151.     }
  152. }
  153.  
  154.  
  155.